Chapter 4. Understanding Ownership in Rust
Introduction
The ownership is the most complex feature of rust, and one that makes the difference with other programming languages. This feature allows you manage in an efficient way (without garbage collector) the space used in memory
Key Concepts
- Borrowing slices
- Lay out data in memory
What is Ownership ?
It is a unique feature of Rust, Understand that will make you to know better how rust manages space in memory and how it replaces garbage collector by a structure and method called the stack and the heap.
The stack and the heap
In many languages this structures does not require to keep in mind, but in rust they get relevance.
whether a value is on the stack or the heap affects how the language behaves and why you have to make certain decisions.
The stack
Think in something like this:

Adding data is called pushing onto the stack. Removing data is called popping off the stack. Data saved in this kind of memory must have a known, fixed size. Data which des not have a known size at compile time or its size can change must be stored on the heap.
The heap
Is less organized. When data is pushed into the heap, it requests a certain amount of space and yhe memory allocator looks for an empty space big enough for requested amount. Then memory allocator marks that space as used and returns a pointer.
This process is called allocating but it is ONLY used when you push data onto the heap, pushing data onto de stack IS NOT considered as allocating.

In this example we can see the pointer, this has a known, fixed size that you can store on the stack, but the actual data is in the heap, so if you want it, you must to follow the pointer.
Differences between the stack and the heap
Pushing data
In this case, obviously, pusing data on the stack is faster than allocating in the heap, because the allocator never has to search for a place to store new data.
Allocating data in the heap requires that allocator has to find a big enough space for that data, and then hold it, perform a bookkeeping to the next allocation.
When a function is called the values passed as parameters, inclusive those pointers to data on the heap, and all local variables are pushed on to the stack and when the function is finished, they get popped off the stack.
Searching data
In the heap this process is slower than in the stack. In the heap you have to follow the pointer to get where the wanted data is.
Ownership Rules
There are some rules to understand this term
- Each value in Rust has an Owner
- There can only be one owner at time
- When the owner goes out of the scope, the value will be dropped.
The Scope
Is the "space" or range in the code where a value or item is valid inside of a program, for example:
// here 's' is not valid
{ // here starts a scope
let s = "hello"; // here we declared 's'
// here 's' is valid
} // here the scope has been finished
// here 's is no longer valid's
The value is valid until it goes out of the current scope
The string type
Relevance of string type
This type is more complex than those seen in Datatypes chapter iii. Those are datatypes with a known size, can be stored on the stack an popped off the stack when their scope is over. Can be quickly and trivially copied to make a new, independent instance if another part of code needs to use the same value in different scope. The string type is different, and also there are other which we'll see further on.
In situations that our code will use values that do not have an specific size, like a user input where we do not know the actual size of that value, this is a useful situation to replace string literals by string type. This type manages data allocated on the heap to store an amount of text that is unknown at compile time.
To create a string type we can those one of these things:
Create a String type from a string literal
Creating a String type from a literal with a value of Hello. The double :: operator allows us to namespace this particular from function under the String type rather than using some sort name like string_from.
let s = String::from("Hello");
Mutating String types
This type can be mutated because its actual storage is on the heap, instead of string literals that are stored on the stack
let mut s = String::from("Hello, ");
s.push_str("world");
println!({s});
Memory and Allocation
There are two steps to follow
- The memory must be requested from the memory allocator at runtime
- We need a way to return this memory to the allocator when we are done with our
String
In the previous example we requested with String::from a space in memory using allocation at runtime. In this step is the same as other programming languages. But it changes with the second step.